<?
/////////////////////////////////////////////////////////////////////////////////////////
// Clase para Manejar Archivos XML como si fuese una Base de datos
/////////////////////////////////////////////////////////////////////////////////////////

class DatabaseXML
	{
		// Propiedades de la Conexion
		var $cFile = "";
		var $cPath = "";
		var $cUser = "";
		var $cPassword = "";
		var $oRoot = 0;
		var $cSql = "";

		function getConnectionHandle()
		{
			if ( $this->oRoot == false )
			{
				$this->connect();
			}
			return $this->oRoot;
		}
		function recordset( $cSql, $nFrom = '', $nLenght = '' )
		{
			// Guara la Consulta
			$this->cSql = $cSql;
			$oRs = new RecordsetXML ( $this );
			$bOk = $oRs->open ( $cSql, $nFrom, $nLenght );
			return $bOk ? $oRs :false;
		}

		function DatabaseXML($cFile, $cPath = "", $cUser = "", $cPassword = "")
		{
			$this->cFile = $cFile;
			if ( $cPath != "" ) $this->readPath( $cPath );
			$this->cUser = $cUser;
			$this->cPassword = $cPassword;
			$this->oRoot = 0;
		}
		//
		function status()
		{
			return 'File: ' . $this->cFile . ' Database: ' . $this->cPath  . ' ConId: ' . $this->oRoot ;
		}
		//
		function connect( )
		{

		}
		function readPath( $cPath )
		{
			if ( $cPath == '' ) return FALSE;
			$nFd = fopen($this->cFile, "r" );
			if ( !$nFd ) return FALSE;
			// Optimizar para que parsear solo desde $this->cPath
			$cHtml = '';
			while( !feof($nFd) )
			{
				$cChar = fread($nFd, 1) ;
				$cHtml .= $cChar;
			}
			fclose($nFd);

			$this->oRoot = parseHtml ( $cHtml , $cPath);
			$this->cPath = $cPath;
			$aPath = explode( '->', $cPath);
			$nNivel = 0;
			$oRoot = $this->oRoot;
			while( $nNivel < count($aPath) )
			{
				$bEncontrado = false;
				// Sepana el Tag del Filtro. Ej Tag[id=x AND tipo=y]
				$nPos = strpos($aPath[$nNivel], '[');
				if ( $nPos === false )
				{
					$cTagName = strtolower($aPath[$nNivel]);
					$cFiltro = '';
				} else
				{
					$cTagName = strtolower( substr($aPath[$nNivel],0, $nPos));
					$cFiltro = substr($aPath[$nNivel],$nPos+1, -1);
					$aFiltro = array();
					foreach( explode(' AND ', $cFiltro) as $cItemFiltro )
					{
						list( $cKey, $cValor ) = explode('=', $cItemFiltro);
						$aFiltro[trim($cKey)] = trim($cValor);
					}
				}
				foreach( $oRoot->elements as $element )
				{
					if ( $element->getTagName() == $cTagName  )
					{
						if ( $cFiltro != '')
						{
							$bFiltro = true;
							foreach( $aFiltro as $cKey => $cValue )
							{
								if ( $element->properties[$cKey] !=  $cValue )
								{
									$bFiltro = false;
									break;
								}
							}
						}
						if ( $cFiltro == '' || $bFiltro == true)
						{
							$bEncontrado = true;
							$nNivel++;
							$oRoot = $element;
							break;
						}
					}
				}
				if ( !$bEncontrado ) { echo "No se encontro" ; return false; }
			}
			return ( $nNivel == count($aPath) ) ? $element: false;
		}
		function getMatrix ( $cSql, $nFrom = '', $nLenght = '' )
		{
		}
		//
		function getKeyArray( $cSql, $nFrom = '', $nLenght = '' )
		{
		}
		//
		function getArray( $cSql )
		{
			$oElement = $this->readPath( $cSql );
			return ( $oElement ) ? $oElement->properties : false;
		}
		//
		function getData( $cSql ) {
		}
	}

class RecordsetXML
	{
		var $oConnection = 0;
		var $nRow= -1;
		var $oRoot;
		var $aFields = array();
		var $aProperties = array();
		var $cSql = "";
		//
		function RecordsetXML( $oConnection )
		{
			$this->oConnection = $oConnection;
		}
		//
		function open( $cPath , $nFrom = '', $nLenght = '' )
		{
			$this->oRoot =  $this->oConnection->readPath($cPath);
			$this->aProperties = $this->oRoot->properties;
			if ( $nLenght)
			{
				$this->nFrom = $nFrom;
				$this->nTo = $nFrom + $nLenght;
				$this->nRow = $nFrom;
			}
			return true;
		}
		//
		function close ()
			{
				$this->oRoot = null;
			}
		//
		function moveTo( $nRow = -1)
		{
			if ( !$this->oRoot ) return false;
			$nNuevaRow  = ( $nRow == -1 ) ? $this->nRow + 1: $nRow;
			if ( $nNuevaRow   < 0 || $nNuevaRow  >  $this->oRoot->count() ) return false;
			if ( $this->nTo   && $nNuevaRow  >  $this->nTo ) return false;
			$this->aFields = $this->oRoot->elements[$nNuevaRow]->properties;
			$this->nRow = $nNuevaRow;
			return true;
		}
		//
		function moveNext( $bAsociativo = 1)
		{
			return $this->moveTo();
		}
		//
		function count()
		{
			if ( !$this->oRoot ) return false;
			return $this->oRoot->count();
		}
	}
?>
